package com.xsir.ditan.miniprogram.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.xsir.ditan.admin.service.IUserService;
import com.xsir.ditan.miniprogram.common.ResponseResult;
import com.xsir.ditan.miniprogram.common.Result;
import com.xsir.ditan.miniprogram.common.ResultStatus;
import com.xsir.ditan.miniprogram.entity.*;
import com.xsir.ditan.admin.entity.User;
import com.xsir.ditan.miniprogram.service.*;
import com.xsir.ditan.miniprogram.util.JsonUtil;
import com.xsir.ditan.miniprogram.util.JwtUtil;
import com.xsir.ditan.miniprogram.util.WeChatUtil;
import com.xsir.ditan.miniprogram.vo.OrderQuery;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.codehaus.groovy.tools.shell.IO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import java.io.File;
import java.io.IOException;
import java.util.*;

/**
 * @author user
 * @date 2021/1/28
 */
@RestController
@RequestMapping("miniprogram")
@Slf4j
public class MiniProgramController {
    @Autowired
    private IAppInfoService appInfoService;
    @Autowired
    private IUserService userService;
    @Autowired
    private IBannerService bannerService;
    @Autowired
    private IGoodsService goodsService;
    @Autowired
    private IGoodsDateService goodsDateService;
    @Autowired
    private ICertificateService certificateService;
    @Autowired
    private IOrderGoodsService orderGoodsService;
    
    
    @PostMapping("/user/login")
    public Result login(@RequestBody Map<String, Object> userInfo) throws Exception {
        // 1、用code获取openid和session_key
        Map map = WeChatUtil.code2Session(userInfo.get("code").toString());
        
        String openId = null;
        String sessionKey = null;
        try {
            openId = (String)map.get("openid");
            sessionKey = (String)map.get("session_key");
        } catch (Exception e) {
            throw new Exception("无效的code");
        }
    
        // 2、检查openid是否已存在
        Map<String, Object> data = new HashMap<>(2);
        AppInfo appInfo = appInfoService.getOne(new QueryWrapper<AppInfo>().eq("open_id", openId));
        // 不存在则添加用户
        if(Objects.isNull(appInfo)) {
            Map<String,Object> userMap = JSON.parseObject(userInfo.get("user_info").toString(), new TypeReference<Map<String,Object>>(){});
            if(userMap == null) {
                return Result.error(ResultStatus.UNKNOWN_ACCOUNT);
            }
            User user = new User();
            user.setNickName(userMap.get("nickName").toString());
            user.setAvatar(userMap.get("avatarUrl").toString());
            userService.save(user);
            log.info(user.toString());
            appInfo = new AppInfo();
            appInfo.setUserId(user.getId());
            appInfo.setOpenId(openId);
            appInfo.setSessionKey(sessionKey);
            appInfoService.save(appInfo);
        }
        // 已存在则直接返回token
        data.put("token", JwtUtil.createJWT(appInfo.getUserId()));
        data.put("user_id", appInfo.getUserId());
        return Result.ok(data);
    }
    
    @GetMapping("/user/detail")
    public Result detail(@RequestParam("token") String token) {
        Claims claims = JwtUtil.parseJWT(token);
        Integer userId = claims.get("uid", Integer.class);
        User user = userService.getById(userId);
        if(user == null) {
            return Result.error(ResultStatus.UNKNOWN_ACCOUNT);
        }
        Map<String,Object> userDetail = new HashMap<>(8);
        userDetail.put("uid", userId);
        userDetail.put("avatar", user.getAvatar());
        userDetail.put("nickName", user.getNickName());
        userDetail.put("status", user.getStatus());
        return Result.ok(userDetail);
    }
    
    @PostMapping("/user/upload")
    public Result upload(MultipartHttpServletRequest request) throws IOException {
        String token = request.getParameter("token");
        Claims claims = JwtUtil.parseJWT(token);
        Integer userId = claims.get("uid", Integer.class);
        MultipartFile idCardPros = request.getFile("id_card_0");
        MultipartFile idCardCons = request.getFile("id_card_1");
        
        userService.cert(userId, idCardPros, idCardCons);
        
        return Result.ok(null);
    }
    
    
    @GetMapping("/index/page")
    public Result index() {
    
        Map<String, Object> data = new HashMap<>(2);
        data.put("banners", bannerService.listByGroup(3));
        data.put("list", goodsService.list());
        return Result.ok(ResultStatus.SUCCESS, data);
    }
    
    @GetMapping("/goods/detail")
    public Result detail(Integer id) {
        Goods goods = goodsService.getById(id);
        List<Banner> banners = bannerService.list(new QueryWrapper<Banner>().eq("id", id));
        List<GoodsDate> goodsDates = goodsDateService.list(new QueryWrapper<GoodsDate>().eq("goods_id", id));
        Map<String,Object> data = new HashMap<>(4);
        data.put("detail", goods);
        data.put("banners", banners);
        data.put("dateList", goodsDates);
        return Result.ok(data);
    }
    
    @PostMapping("/order/add")
    public Result addOrder(@RequestBody OrderQuery orderQuery) {
        String token = orderQuery.getToken();
        Claims claims = JwtUtil.parseJWT(token);
        Integer uid = claims.get("uid", Integer.class);
        return orderGoodsService.addFromMini(uid, orderQuery.getGoodsId(), orderQuery.getDateList());
    }
    
    @GetMapping("/order/list")
    public Result orderList(String token, String status) {
        if(StringUtils.isBlank(token) || StringUtils.isBlank(status)) {
            return Result.error(ResultStatus.PARAM_IS_BLANK);
        }
        Claims claims = JwtUtil.parseJWT(token);
        Integer uid = claims.get("uid", Integer.class);
        return orderGoodsService.listForMini(uid, status);
    }
    
    @PostMapping("/order/cancel")
    public Result orderCancel(String id, String token) {
        Claims claims = JwtUtil.parseJWT(token);
        Integer uid = claims.get("uid", Integer.class);
        orderGoodsService.removeById(id);
        return orderGoodsService.listForMini(uid, "all");
    }
}
